/*
  author Sylvain Bertrand <sylvain.bertrand@gmail.com>
  Protected by linux GNU GPLv2
  Copyright 2012-2014
*/
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/firmware.h>
#include <linux/cdev.h>

#include <alga/rng_mng.h>
#include <uapi/alga/pixel_fmts.h>
#include <alga/timing.h>
#include <alga/amd/atombios/atb.h>
#include <uapi/alga/amd/dce6/dce6.h>
#include <uapi/alga/amd/si/pkt.h>
#include <uapi/alga/amd/si/gpu_regs_ctx.h>

#include "mc.h"
#include "rlc.h"
#include "ih.h"
#include "fence.h"
#include "ring.h"
#include "dmas.h"
#include "ba.h"
#include "cps.h"
#include "gpu.h"
#include "drv.h"

#define SECTION_ID_NONE		0
#define SECTION_ID_CTX		1
#define SECTION_ID_CLR		2
#define SECTION_ID_CTL_CONST	3

struct clearstate_extent_def {
	u32 *extent;
	u32 reg_idx;
	u32 reg_cnt;
};

struct clearstate_section_def {
    struct clearstate_extent_def *section;
    u8 id;
};

static u32 section_ctx_def_0[] = {
    0x00000000, /* DB_RENDER_CTL */
    0x00000000, /* DB_CNT_CTL */
    0x00000000, /* DB_DEPTH_VIEW */
    0x00000000, /* DB_RENDER_OVERRIDE */
    0x00000000, /* DB_RENDER_OVERRIDE2 */
    0x00000000, /* DB_HTILE_DATA_BASE */
    0, /* HOLE */
    0, /* HOLE */
    0x00000000, /* DB_DEPTH_BOUNDS_MIN */
    0x00000000, /* DB_DEPTH_BOUNDS_MAX */
    0x00000000, /* DB_STENCIL_CLR */
    0x00000000, /* DB_DEPTH_CLR */
    0x00000000, /* PA_SC_SCR_SCISSOR_TL */
    0x40004000, /* PA_SC_SCR_SCISSOR_BR */
    0, /* HOLE */
    0x00000000, /* DB_DEPTH_INFO */
    0x00000000, /* DB_Z_INFO */
    0x00000000, /* DB_STENCIL_INFO */
    0x00000000, /* DB_Z_RD_BASE */
    0x00000000, /* DB_STENCIL_RD_BASE */
    0x00000000, /* DB_Z_WR_BASE */
    0x00000000, /* DB_STENCIL_WR_BASE */
    0x00000000, /* DB_DEPTH_SZ */
    0x00000000, /* DB_DEPTH_SLICE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0x00000000, /* TA_BC_BASE_ADDR */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0x00000000, /* COHER_DEST_BASE_2 */
    0x00000000, /* COHER_DEST_BASE_3 */
    0x00000000, /* PA_SC_WND_OF */
    0x80000000, /* PA_SC_WND_SCISSOR_TL */
    0x40004000, /* PA_SC_WND_SCISSOR_BR */
    0x0000ffff, /* PA_SC_CLIPRECT_RULE */
    0x00000000, /* PA_SC_CLIPRECT_0_TL */
    0x40004000, /* PA_SC_CLIPRECT_0_BR */
    0x00000000, /* PA_SC_CLIPRECT_1_TL */
    0x40004000, /* PA_SC_CLIPRECT_1_BR */
    0x00000000, /* PA_SC_CLIPRECT_2_TL */
    0x40004000, /* PA_SC_CLIPRECT_2_BR */
    0x00000000, /* PA_SC_CLIPRECT_3_TL */
    0x40004000, /* PA_SC_CLIPRECT_3_BR */
    0xaa99aaaa, /* PA_SC_EDGERULE */
    0x00000000, /* PA_SU_HW_SCR_OF */
    0xffffffff, /* CB_TGT_MASK */
    0xffffffff, /* CB_SHADER_MASK */
    0x80000000, /* PA_SC_GENERIC_SCISSOR_TL */
    0x40004000, /* PA_SC_GENERIC_SCISSOR_BR */
    0x00000000, /* COHER_DEST_BASE_0 */
    0x00000000, /* COHER_DEST_BASE_1 */
    0x80000000, /* PA_SC_VPORT_SCISSOR_0_TL */
    0x40004000, /* PA_SC_VPORT_SCISSOR_0_BR */
    0x80000000, /* PA_SC_VPORT_SCISSOR_1_TL */
    0x40004000, /* PA_SC_VPORT_SCISSOR_1_BR */
    0x80000000, /* PA_SC_VPORT_SCISSOR_2_TL */
    0x40004000, /* PA_SC_VPORT_SCISSOR_2_BR */
    0x80000000, /* PA_SC_VPORT_SCISSOR_3_TL */
    0x40004000, /* PA_SC_VPORT_SCISSOR_3_BR */
    0x80000000, /* PA_SC_VPORT_SCISSOR_4_TL */
    0x40004000, /* PA_SC_VPORT_SCISSOR_4_BR */
    0x80000000, /* PA_SC_VPORT_SCISSOR_5_TL */
    0x40004000, /* PA_SC_VPORT_SCISSOR_5_BR */
    0x80000000, /* PA_SC_VPORT_SCISSOR_6_TL */
    0x40004000, /* PA_SC_VPORT_SCISSOR_6_BR */
    0x80000000, /* PA_SC_VPORT_SCISSOR_7_TL */
    0x40004000, /* PA_SC_VPORT_SCISSOR_7_BR */
    0x80000000, /* PA_SC_VPORT_SCISSOR_8_TL */
    0x40004000, /* PA_SC_VPORT_SCISSOR_8_BR */
    0x80000000, /* PA_SC_VPORT_SCISSOR_9_TL */
    0x40004000, /* PA_SC_VPORT_SCISSOR_9_BR */
    0x80000000, /* PA_SC_VPORT_SCISSOR_10_TL */
    0x40004000, /* PA_SC_VPORT_SCISSOR_10_BR */
    0x80000000, /* PA_SC_VPORT_SCISSOR_11_TL */
    0x40004000, /* PA_SC_VPORT_SCISSOR_11_BR */
    0x80000000, /* PA_SC_VPORT_SCISSOR_12_TL */
    0x40004000, /* PA_SC_VPORT_SCISSOR_12_BR */
    0x80000000, /* PA_SC_VPORT_SCISSOR_13_TL */
    0x40004000, /* PA_SC_VPORT_SCISSOR_13_BR */
    0x80000000, /* PA_SC_VPORT_SCISSOR_14_TL */
    0x40004000, /* PA_SC_VPORT_SCISSOR_14_BR */
    0x80000000, /* PA_SC_VPORT_SCISSOR_15_TL */
    0x40004000, /* PA_SC_VPORT_SCISSOR_15_BR */
    0x00000000, /* PA_SC_VPORT_ZMIN_0 */
    0x3f800000, /* PA_SC_VPORT_ZMAX_0 */
    0x00000000, /* PA_SC_VPORT_ZMIN_1 */
    0x3f800000, /* PA_SC_VPORT_ZMAX_1 */
    0x00000000, /* PA_SC_VPORT_ZMIN_2 */
    0x3f800000, /* PA_SC_VPORT_ZMAX_2 */
    0x00000000, /* PA_SC_VPORT_ZMIN_3 */
    0x3f800000, /* PA_SC_VPORT_ZMAX_3 */
    0x00000000, /* PA_SC_VPORT_ZMIN_4 */
    0x3f800000, /* PA_SC_VPORT_ZMAX_4 */
    0x00000000, /* PA_SC_VPORT_ZMIN_5 */
    0x3f800000, /* PA_SC_VPORT_ZMAX_5 */
    0x00000000, /* PA_SC_VPORT_ZMIN_6 */
    0x3f800000, /* PA_SC_VPORT_ZMAX_6 */
    0x00000000, /* PA_SC_VPORT_ZMIN_7 */
    0x3f800000, /* PA_SC_VPORT_ZMAX_7 */
    0x00000000, /* PA_SC_VPORT_ZMIN_8 */
    0x3f800000, /* PA_SC_VPORT_ZMAX_8 */
    0x00000000, /* PA_SC_VPORT_ZMIN_9 */
    0x3f800000, /* PA_SC_VPORT_ZMAX_9 */
    0x00000000, /* PA_SC_VPORT_ZMIN_10 */
    0x3f800000, /* PA_SC_VPORT_ZMAX_10 */
    0x00000000, /* PA_SC_VPORT_ZMIN_11 */
    0x3f800000, /* PA_SC_VPORT_ZMAX_11 */
    0x00000000, /* PA_SC_VPORT_ZMIN_12 */
    0x3f800000, /* PA_SC_VPORT_ZMAX_12 */
    0x00000000, /* PA_SC_VPORT_ZMIN_13 */
    0x3f800000, /* PA_SC_VPORT_ZMAX_13 */
    0x00000000, /* PA_SC_VPORT_ZMIN_14 */
    0x3f800000, /* PA_SC_VPORT_ZMAX_14 */
    0x00000000, /* PA_SC_VPORT_ZMIN_15 */
    0x3f800000, /* PA_SC_VPORT_ZMAX_15 */
};

static u32 section_ctx_def_1[] = {
    0x00000000, /* CP_PERFMON_CTX_CTL */
    0x00000000, /* CP_RING_ID */
    0x00000000, /* CP_VM_ID */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0xffffffff, /* VGT_MAX_VTX_IDX */
    0x00000000, /* VGT_MIN_VTX_IDX */
    0x00000000, /* VGT_IDX_OFF */
    0x00000000, /* VGT_MULTI_PRIM_IB_RESET_IDX */
    0, /* HOLE */
    0x00000000, /* CB_BLEND_RED */
    0x00000000, /* CB_BLEND_GREEN */
    0x00000000, /* CB_BLEND_BLUE */
    0x00000000, /* CB_BLEND_ALPHA */
    0, /* HOLE */
    0, /* HOLE */
    0x00000000, /* DB_STENCIL_CTL */
    0x00000000, /* DB_STENCILREFMASK */
    0x00000000, /* DB_STENCILREFMASK_BF */
    0, /* HOLE */
    0x00000000, /* PA_CL_VPORT_XSCALE */
    0x00000000, /* PA_CL_VPORT_XOF */
    0x00000000, /* PA_CL_VPORT_YSCALE */
    0x00000000, /* PA_CL_VPORT_YOF */
    0x00000000, /* PA_CL_VPORT_ZSCALE */
    0x00000000, /* PA_CL_VPORT_ZOF */
    0x00000000, /* PA_CL_VPORT_XSCALE_1 */
    0x00000000, /* PA_CL_VPORT_XOF_1 */
    0x00000000, /* PA_CL_VPORT_YSCALE_1 */
    0x00000000, /* PA_CL_VPORT_YOF_1 */
    0x00000000, /* PA_CL_VPORT_ZSCALE_1 */
    0x00000000, /* PA_CL_VPORT_ZOF_1 */
    0x00000000, /* PA_CL_VPORT_XSCALE_2 */
    0x00000000, /* PA_CL_VPORT_XOF_2 */
    0x00000000, /* PA_CL_VPORT_YSCALE_2 */
    0x00000000, /* PA_CL_VPORT_YOF_2 */
    0x00000000, /* PA_CL_VPORT_ZSCALE_2 */
    0x00000000, /* PA_CL_VPORT_ZOF_2 */
    0x00000000, /* PA_CL_VPORT_XSCALE_3 */
    0x00000000, /* PA_CL_VPORT_XOF_3 */
    0x00000000, /* PA_CL_VPORT_YSCALE_3 */
    0x00000000, /* PA_CL_VPORT_YOF_3 */
    0x00000000, /* PA_CL_VPORT_ZSCALE_3 */
    0x00000000, /* PA_CL_VPORT_ZOF_3 */
    0x00000000, /* PA_CL_VPORT_XSCALE_4 */
    0x00000000, /* PA_CL_VPORT_XOF_4 */
    0x00000000, /* PA_CL_VPORT_YSCALE_4 */
    0x00000000, /* PA_CL_VPORT_YOF_4 */
    0x00000000, /* PA_CL_VPORT_ZSCALE_4 */
    0x00000000, /* PA_CL_VPORT_ZOF_4 */
    0x00000000, /* PA_CL_VPORT_XSCALE_5 */
    0x00000000, /* PA_CL_VPORT_XOF_5 */
    0x00000000, /* PA_CL_VPORT_YSCALE_5 */
    0x00000000, /* PA_CL_VPORT_YOF_5 */
    0x00000000, /* PA_CL_VPORT_ZSCALE_5 */
    0x00000000, /* PA_CL_VPORT_ZOF_5 */
    0x00000000, /* PA_CL_VPORT_XSCALE_6 */
    0x00000000, /* PA_CL_VPORT_XOF_6 */
    0x00000000, /* PA_CL_VPORT_YSCALE_6 */
    0x00000000, /* PA_CL_VPORT_YOF_6 */
    0x00000000, /* PA_CL_VPORT_ZSCALE_6 */
    0x00000000, /* PA_CL_VPORT_ZOF_6 */
    0x00000000, /* PA_CL_VPORT_XSCALE_7 */
    0x00000000, /* PA_CL_VPORT_XOF_7 */
    0x00000000, /* PA_CL_VPORT_YSCALE_7 */
    0x00000000, /* PA_CL_VPORT_YOF_7 */
    0x00000000, /* PA_CL_VPORT_ZSCALE_7 */
    0x00000000, /* PA_CL_VPORT_ZOF_7 */
    0x00000000, /* PA_CL_VPORT_XSCALE_8 */
    0x00000000, /* PA_CL_VPORT_XOF_8 */
    0x00000000, /* PA_CL_VPORT_YSCALE_8 */
    0x00000000, /* PA_CL_VPORT_YOF_8 */
    0x00000000, /* PA_CL_VPORT_ZSCALE_8 */
    0x00000000, /* PA_CL_VPORT_ZOF_8 */
    0x00000000, /* PA_CL_VPORT_XSCALE_9 */
    0x00000000, /* PA_CL_VPORT_XOF_9 */
    0x00000000, /* PA_CL_VPORT_YSCALE_9 */
    0x00000000, /* PA_CL_VPORT_YOF_9 */
    0x00000000, /* PA_CL_VPORT_ZSCALE_9 */
    0x00000000, /* PA_CL_VPORT_ZOF_9 */
    0x00000000, /* PA_CL_VPORT_XSCALE_10 */
    0x00000000, /* PA_CL_VPORT_XOF_10 */
    0x00000000, /* PA_CL_VPORT_YSCALE_10 */
    0x00000000, /* PA_CL_VPORT_YOF_10 */
    0x00000000, /* PA_CL_VPORT_ZSCALE_10 */
    0x00000000, /* PA_CL_VPORT_ZOF_10 */
    0x00000000, /* PA_CL_VPORT_XSCALE_11 */
    0x00000000, /* PA_CL_VPORT_XOF_11 */
    0x00000000, /* PA_CL_VPORT_YSCALE_11 */
    0x00000000, /* PA_CL_VPORT_YOF_11 */
    0x00000000, /* PA_CL_VPORT_ZSCALE_11 */
    0x00000000, /* PA_CL_VPORT_ZOF_11 */
    0x00000000, /* PA_CL_VPORT_XSCALE_12 */
    0x00000000, /* PA_CL_VPORT_XOF_12 */
    0x00000000, /* PA_CL_VPORT_YSCALE_12 */
    0x00000000, /* PA_CL_VPORT_YOF_12 */
    0x00000000, /* PA_CL_VPORT_ZSCALE_12 */
    0x00000000, /* PA_CL_VPORT_ZOF_12 */
    0x00000000, /* PA_CL_VPORT_XSCALE_13 */
    0x00000000, /* PA_CL_VPORT_XOF_13 */
    0x00000000, /* PA_CL_VPORT_YSCALE_13 */
    0x00000000, /* PA_CL_VPORT_YOF_13 */
    0x00000000, /* PA_CL_VPORT_ZSCALE_13 */
    0x00000000, /* PA_CL_VPORT_ZOF_13 */
    0x00000000, /* PA_CL_VPORT_XSCALE_14 */
    0x00000000, /* PA_CL_VPORT_XOF_14 */
    0x00000000, /* PA_CL_VPORT_YSCALE_14 */
    0x00000000, /* PA_CL_VPORT_YOF_14 */
    0x00000000, /* PA_CL_VPORT_ZSCALE_14 */
    0x00000000, /* PA_CL_VPORT_ZOF_14 */
    0x00000000, /* PA_CL_VPORT_XSCALE_15 */
    0x00000000, /* PA_CL_VPORT_XOF_15 */
    0x00000000, /* PA_CL_VPORT_YSCALE_15 */
    0x00000000, /* PA_CL_VPORT_YOF_15 */
    0x00000000, /* PA_CL_VPORT_ZSCALE_15 */
    0x00000000, /* PA_CL_VPORT_ZOF_15 */
    0x00000000, /* PA_CL_UCP_0_X */
    0x00000000, /* PA_CL_UCP_0_Y */
    0x00000000, /* PA_CL_UCP_0_Z */
    0x00000000, /* PA_CL_UCP_0_W */
    0x00000000, /* PA_CL_UCP_1_X */
    0x00000000, /* PA_CL_UCP_1_Y */
    0x00000000, /* PA_CL_UCP_1_Z */
    0x00000000, /* PA_CL_UCP_1_W */
    0x00000000, /* PA_CL_UCP_2_X */
    0x00000000, /* PA_CL_UCP_2_Y */
    0x00000000, /* PA_CL_UCP_2_Z */
    0x00000000, /* PA_CL_UCP_2_W */
    0x00000000, /* PA_CL_UCP_3_X */
    0x00000000, /* PA_CL_UCP_3_Y */
    0x00000000, /* PA_CL_UCP_3_Z */
    0x00000000, /* PA_CL_UCP_3_W */
    0x00000000, /* PA_CL_UCP_4_X */
    0x00000000, /* PA_CL_UCP_4_Y */
    0x00000000, /* PA_CL_UCP_4_Z */
    0x00000000, /* PA_CL_UCP_4_W */
    0x00000000, /* PA_CL_UCP_5_X */
    0x00000000, /* PA_CL_UCP_5_Y */
    0x00000000, /* PA_CL_UCP_5_Z */
    0x00000000, /* PA_CL_UCP_5_W */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0x00000000, /* SPI_PS_INPUT_CTL_0 */
    0x00000000, /* SPI_PS_INPUT_CTL_1 */
    0x00000000, /* SPI_PS_INPUT_CTL_2 */
    0x00000000, /* SPI_PS_INPUT_CTL_3 */
    0x00000000, /* SPI_PS_INPUT_CTL_4 */
    0x00000000, /* SPI_PS_INPUT_CTL_5 */
    0x00000000, /* SPI_PS_INPUT_CTL_6 */
    0x00000000, /* SPI_PS_INPUT_CTL_7 */
    0x00000000, /* SPI_PS_INPUT_CTL_8 */
    0x00000000, /* SPI_PS_INPUT_CTL_9 */
    0x00000000, /* SPI_PS_INPUT_CTL_10 */
    0x00000000, /* SPI_PS_INPUT_CTL_11 */
    0x00000000, /* SPI_PS_INPUT_CTL_12 */
    0x00000000, /* SPI_PS_INPUT_CTL_13 */
    0x00000000, /* SPI_PS_INPUT_CTL_14 */
    0x00000000, /* SPI_PS_INPUT_CTL_15 */
    0x00000000, /* SPI_PS_INPUT_CTL_16 */
    0x00000000, /* SPI_PS_INPUT_CTL_17 */
    0x00000000, /* SPI_PS_INPUT_CTL_18 */
    0x00000000, /* SPI_PS_INPUT_CTL_19 */
    0x00000000, /* SPI_PS_INPUT_CTL_20 */
    0x00000000, /* SPI_PS_INPUT_CTL_21 */
    0x00000000, /* SPI_PS_INPUT_CTL_22 */
    0x00000000, /* SPI_PS_INPUT_CTL_23 */
    0x00000000, /* SPI_PS_INPUT_CTL_24 */
    0x00000000, /* SPI_PS_INPUT_CTL_25 */
    0x00000000, /* SPI_PS_INPUT_CTL_26 */
    0x00000000, /* SPI_PS_INPUT_CTL_27 */
    0x00000000, /* SPI_PS_INPUT_CTL_28 */
    0x00000000, /* SPI_PS_INPUT_CTL_29 */
    0x00000000, /* SPI_PS_INPUT_CTL_30 */
    0x00000000, /* SPI_PS_INPUT_CTL_31 */
    0x00000000, /* SPI_VS_OUT_CFG */
    0, /* HOLE */
    0x00000000, /* SPI_PS_INPUT_ENA */
    0x00000000, /* SPI_PS_INPUT_ADDR */
    0x00000000, /* SPI_INTERP_CTL_0 */
    0x00000002, /* SPI_PS_IN_CTL */
    0, /* HOLE */
    0x00000000, /* SPI_BARYC_CTL */
    0, /* HOLE */
    0x00000000, /* SPI_TMP_RING_SZ */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0x00000000, /* SPI_WAVE_MGMT_1 */
    0x00000000, /* SPI_WAVE_MGMT_2 */
    0x00000000, /* SPI_SHADER_POS_FMT */
    0x00000000, /* SPI_SHADER_Z_FMT */
    0x00000000, /* SPI_SHADER_COL_FMT */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0x00000000, /* CB_BLEND0_CTL */
    0x00000000, /* CB_BLEND1_CTL */
    0x00000000, /* CB_BLEND2_CTL */
    0x00000000, /* CB_BLEND3_CTL */
    0x00000000, /* CB_BLEND4_CTL */
    0x00000000, /* CB_BLEND5_CTL */
    0x00000000, /* CB_BLEND6_CTL */
    0x00000000, /* CB_BLEND7_CTL */
};

static u32 section_ctx_def_2[] = {
    0x00000000, /* PA_CL_POINT_X_RAD */
    0x00000000, /* PA_CL_POINT_Y_RAD */
    0x00000000, /* PA_CL_POINT_SZ */
    0x00000000, /* PA_CL_POINT_CULL_RAD */
    0x00000000, /* VGT_DMA_BASE_HI */
    0x00000000, /* VGT_DMA_BASE */
};

static u32 section_ctx_def_3[] = {
    0x00000000, /* DB_DEPTH_CTL */
    0x00000000, /* DB_EQAA */
    0x00000000, /* CB_COLOR_CTL */
    0x00000000, /* DB_SHADER_CTL */
    0x00090000, /* PA_CL_CLIP_CTL */
    0x00000004, /* PA_SU_SC_MODE_CTL */
    0x00000000, /* PA_CL_VTE_CTL */
    0x00000000, /* PA_CL_VS_OUT_CTL */
    0x00000000, /* PA_CL_NANINF_CTL */
    0x00000000, /* PA_SU_LINE_STIPPLE_CTL */
    0x00000000, /* PA_SU_LINE_STIPPLE_SCALE */
    0x00000000, /* PA_SU_PRIM_FILTER_CTL */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0x00000000, /* PA_SU_POINT_SZ */
    0x00000000, /* PA_SU_POINT_MINMAX */
    0x00000000, /* PA_SU_LINE_CTL */
    0x00000000, /* PA_SC_LINE_STIPPLE */
    0x00000000, /* VGT_OUTPUT_PATH_CTL */
    0x00000000, /* VGT_HOS_CTL */
    0x00000000, /* VGT_HOS_MAX_TESS_LVL */
    0x00000000, /* VGT_HOS_MIN_TESS_LVL */
    0x00000000, /* VGT_HOS_REUSE_DEPTH */
    0x00000000, /* VGT_GROUP_PRIM_TYPE */
    0x00000000, /* VGT_GROUP_FIRST_DECR */
    0x00000000, /* VGT_GROUP_DECR */
    0x00000000, /* VGT_GROUP_VECT_0_CTL */
    0x00000000, /* VGT_GROUP_VECT_1_CTL */
    0x00000000, /* VGT_GROUP_VECT_0_FMT_CTL */
    0x00000000, /* VGT_GROUP_VECT_1_FMT_CTL */
    0x00000000, /* VGT_GS_MODE */
    0, /* HOLE */
    0x00000000, /* PA_SC_MODE_CTL_0 */
    0x00000000, /* PA_SC_MODE_CTL_1 */
    0x00000000, /* VGT_ENHANCE */
    0x00000100, /* VGT_GS_PER_ES */
    0x00000080, /* VGT_ES_PER_GS */
    0x00000002, /* VGT_GS_PER_VS */
    0x00000000, /* VGT_GSVS_RING_OFF_1 */
    0x00000000, /* VGT_GSVS_RING_OFF_2 */
    0x00000000, /* VGT_GSVS_RING_OFF_3 */
    0x00000000, /* VGT_GS_OUT_PRIM_TYPE */
    0x00000000, /* IA_ENHANCE */
};

static u32 section_ctx_def_4[] = {
    0x00000000, /* VGT_PRIM_ID_ENA */
};

static u32 section_ctx_def_5[] = {
    0x00000000, /* VGT_PRIM_ID_RESET */
};

static u32 section_ctx_def_6[] = {
    0x00000000, /* VGT_MULTI_PRIM_IB_RESET_ENA */
    0, /* HOLE */
    0, /* HOLE */
    0x00000000, /* VGT_INSTANCE_STEP_RATE_0 */
    0x00000000, /* VGT_INSTANCE_STEP_RATE_1 */
    0x000000ff, /* IA_MULTI_VGT_PARAM */
    0x00000000, /* VGT_ESGS_RING_ITEM_SZ */
    0x00000000, /* VGT_GSVS_RING_ITEM_SZ */
    0x00000000, /* VGT_REUSE_OFF */
    0x00000000, /* VGT_VTX_CNT_ENA */
    0x00000000, /* DB_HTILE_SURF */
    0x00000000, /* DB_SRESULTS_COMPARE_STATE0 */
    0x00000000, /* DB_SRESULTS_COMPARE_STATE1 */
    0x00000000, /* DB_PRELOAD_CTL */
    0, /* HOLE */
    0x00000000, /* VGT_STRMOUT_BUF_SZ_0 */
    0x00000000, /* VGT_STRMOUT_VTX_STRIDE_0 */
    0, /* HOLE */
    0x00000000, /* VGT_STRMOUT_BUF_OF_0 */
    0x00000000, /* VGT_STRMOUT_BUF_SZ_1 */
    0x00000000, /* VGT_STRMOUT_VTX_STRIDE_1 */
    0, /* HOLE */
    0x00000000, /* VGT_STRMOUT_BUF_OF_1 */
    0x00000000, /* VGT_STRMOUT_BUF_SZ_2 */
    0x00000000, /* VGT_STRMOUT_VTX_STRIDE_2 */
    0, /* HOLE */
    0x00000000, /* VGT_STRMOUT_BUF_OF_2 */
    0x00000000, /* VGT_STRMOUT_BUF_SZ_3 */
    0x00000000, /* VGT_STRMOUT_VTX_STRIDE_3 */
    0, /* HOLE */
    0x00000000, /* VGT_STRMOUT_BUF_OF_3 */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0x00000000, /* VGT_STRMOUT_DRAW_OPAQUE_OF */
    0x00000000, /* VGT_STRMOUT_DRAW_OPAQUE_BUF_FILLED_SZ */
    0x00000000, /* VGT_STRMOUT_DRAW_OPAQUE_VTX_STRIDE */
    0, /* HOLE */
    0x00000000, /* VGT_GS_MAX_VERT_OUT */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0x00000000, /* VGT_SHADER_STAGES_ENA */
    0x00000000, /* VGT_LS_HS_CFG */
    0x00000000, /* VGT_GS_VERT_ITEM_SZ */
    0x00000000, /* VGT_GS_VERT_ITEM_SZ_1 */
    0x00000000, /* VGT_GS_VERT_ITEM_SZ_2 */
    0x00000000, /* VGT_GS_VERT_ITEM_SZ_3 */
    0x00000000, /* VGT_TF_PARAM */
    0x00000000, /* DB_ALPHA_TO_MASK */
    0, /* HOLE */
    0x00000000, /* PA_SU_POLY_OF_DB_FMT_CTL */
    0x00000000, /* PA_SU_POLY_OF_CLAMP */
    0x00000000, /* PA_SU_POLY_OF_FRONT_SCALE */
    0x00000000, /* PA_SU_POLY_OF_FRONT_OF */
    0x00000000, /* PA_SU_POLY_OF_BACK_SCALE */
    0x00000000, /* PA_SU_POLY_OF_BACK_OF */
    0x00000000, /* VGT_GS_INSTANCE_CNT */
    0x00000000, /* VGT_STRMOUT_CFG */
    0x00000000, /* VGT_STRMOUT_BUF_CFG */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0x00000000, /* PA_SC_CENTROID_PRIORITY_0 */
    0x00000000, /* PA_SC_CENTROID_PRIORITY_1 */
    0x00001000, /* PA_SC_LINE_CTL */
    0x00000000, /* PA_SC_AA_CFG */
    0x00000005, /* PA_SU_VTX_CTL */
    0x3f800000, /* PA_CL_GB_VERT_CLIP_ADJ */
    0x3f800000, /* PA_CL_GB_VERT_DISC_ADJ */
    0x3f800000, /* PA_CL_GB_HORZ_CLIP_ADJ */
    0x3f800000, /* PA_CL_GB_HORZ_DISC_ADJ */
    0x00000000, /* PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0 */
    0x00000000, /* PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_1 */
    0x00000000, /* PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_2 */
    0x00000000, /* PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_3 */
    0x00000000, /* PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_0 */
    0x00000000, /* PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_1 */
    0x00000000, /* PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_2 */
    0x00000000, /* PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_3 */
    0x00000000, /* PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_0 */
    0x00000000, /* PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_1 */
    0x00000000, /* PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_2 */
    0x00000000, /* PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_3 */
    0x00000000, /* PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_0 */
    0x00000000, /* PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_1 */
    0x00000000, /* PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_2 */
    0x00000000, /* PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_3 */
    0xffffffff, /* PA_SC_AA_MASK_X0Y0_X1Y0 */
    0xffffffff, /* PA_SC_AA_MASK_X0Y1_X1Y1 */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0, /* HOLE */
    0x0000000e, /* VGT_VTX_REUSE_BLK_CTL */
    0x00000010, /* VGT_OUT_DEALLOC_CTL */
    0x00000000, /* CB_COLOR0_BASE */
    0x00000000, /* CB_COLOR0_PITCH */
    0x00000000, /* CB_COLOR0_SLICE */
    0x00000000, /* CB_COLOR0_VIEW */
    0x00000000, /* CB_COLOR0_INFO */
    0x00000000, /* CB_COLOR0_ATTRIB */
    0, /* HOLE */
    0x00000000, /* CB_COLOR0_CMASK */
    0x00000000, /* CB_COLOR0_CMASK_SLICE */
    0x00000000, /* CB_COLOR0_FMASK */
    0x00000000, /* CB_COLOR0_FMASK_SLICE */
    0x00000000, /* CB_COLOR0_CLR_WORD0 */
    0x00000000, /* CB_COLOR0_CLR_WORD1 */
    0, /* HOLE */
    0, /* HOLE */
    0x00000000, /* CB_COLOR1_BASE */
    0x00000000, /* CB_COLOR1_PITCH */
    0x00000000, /* CB_COLOR1_SLICE */
    0x00000000, /* CB_COLOR1_VIEW */
    0x00000000, /* CB_COLOR1_INFO */
    0x00000000, /* CB_COLOR1_ATTRIB */
    0, /* HOLE */
    0x00000000, /* CB_COLOR1_CMASK */
    0x00000000, /* CB_COLOR1_CMASK_SLICE */
    0x00000000, /* CB_COLOR1_FMASK */
    0x00000000, /* CB_COLOR1_FMASK_SLICE */
    0x00000000, /* CB_COLOR1_CLR_WORD0 */
    0x00000000, /* CB_COLOR1_CLR_WORD1 */
    0, /* HOLE */
    0, /* HOLE */
    0x00000000, /* CB_COLOR2_BASE */
    0x00000000, /* CB_COLOR2_PITCH */
    0x00000000, /* CB_COLOR2_SLICE */
    0x00000000, /* CB_COLOR2_VIEW */
    0x00000000, /* CB_COLOR2_INFO */
    0x00000000, /* CB_COLOR2_ATTRIB */
    0, /* HOLE */
    0x00000000, /* CB_COLOR2_CMASK */
    0x00000000, /* CB_COLOR2_CMASK_SLICE */
    0x00000000, /* CB_COLOR2_FMASK */
    0x00000000, /* CB_COLOR2_FMASK_SLICE */
    0x00000000, /* CB_COLOR2_CLR_WORD0 */
    0x00000000, /* CB_COLOR2_CLR_WORD1 */
    0, /* HOLE */
    0, /* HOLE */
    0x00000000, /* CB_COLOR3_BASE */
    0x00000000, /* CB_COLOR3_PITCH */
    0x00000000, /* CB_COLOR3_SLICE */
    0x00000000, /* CB_COLOR3_VIEW */
    0x00000000, /* CB_COLOR3_INFO */
    0x00000000, /* CB_COLOR3_ATTRIB */
    0, /* HOLE */
    0x00000000, /* CB_COLOR3_CMASK */
    0x00000000, /* CB_COLOR3_CMASK_SLICE */
    0x00000000, /* CB_COLOR3_FMASK */
    0x00000000, /* CB_COLOR3_FMASK_SLICE */
    0x00000000, /* CB_COLOR3_CLR_WORD0 */
    0x00000000, /* CB_COLOR3_CLR_WORD1 */
    0, /* HOLE */
    0, /* HOLE */
    0x00000000, /* CB_COLOR4_BASE */
    0x00000000, /* CB_COLOR4_PITCH */
    0x00000000, /* CB_COLOR4_SLICE */
    0x00000000, /* CB_COLOR4_VIEW */
    0x00000000, /* CB_COLOR4_INFO */
    0x00000000, /* CB_COLOR4_ATTRIB */
    0, /* HOLE */
    0x00000000, /* CB_COLOR4_CMASK */
    0x00000000, /* CB_COLOR4_CMASK_SLICE */
    0x00000000, /* CB_COLOR4_FMASK */
    0x00000000, /* CB_COLOR4_FMASK_SLICE */
    0x00000000, /* CB_COLOR4_CLR_WORD0 */
    0x00000000, /* CB_COLOR4_CLR_WORD1 */
    0, /* HOLE */
    0, /* HOLE */
    0x00000000, /* CB_COLOR5_BASE */
    0x00000000, /* CB_COLOR5_PITCH */
    0x00000000, /* CB_COLOR5_SLICE */
    0x00000000, /* CB_COLOR5_VIEW */
    0x00000000, /* CB_COLOR5_INFO */
    0x00000000, /* CB_COLOR5_ATTRIB */
    0, /* HOLE */
    0x00000000, /* CB_COLOR5_CMASK */
    0x00000000, /* CB_COLOR5_CMASK_SLICE */
    0x00000000, /* CB_COLOR5_FMASK */
    0x00000000, /* CB_COLOR5_FMASK_SLICE */
    0x00000000, /* CB_COLOR5_CLR_WORD0 */
    0x00000000, /* CB_COLOR5_CLR_WORD1 */
    0, /* HOLE */
    0, /* HOLE */
    0x00000000, /* CB_COLOR6_BASE */
    0x00000000, /* CB_COLOR6_PITCH */
    0x00000000, /* CB_COLOR6_SLICE */
    0x00000000, /* CB_COLOR6_VIEW */
    0x00000000, /* CB_COLOR6_INFO */
    0x00000000, /* CB_COLOR6_ATTRIB */
    0, /* HOLE */
    0x00000000, /* CB_COLOR6_CMASK */
    0x00000000, /* CB_COLOR6_CMASK_SLICE */
    0x00000000, /* CB_COLOR6_FMASK */
    0x00000000, /* CB_COLOR6_FMASK_SLICE */
    0x00000000, /* CB_COLOR6_CLR_WORD0 */
    0x00000000, /* CB_COLOR6_CLR_WORD1 */
    0, /* HOLE */
    0, /* HOLE */
    0x00000000, /* CB_COLOR7_BASE */
    0x00000000, /* CB_COLOR7_PITCH */
    0x00000000, /* CB_COLOR7_SLICE */
    0x00000000, /* CB_COLOR7_VIEW */
    0x00000000, /* CB_COLOR7_INFO */
    0x00000000, /* CB_COLOR7_ATTRIB */
    0, /* HOLE */
    0x00000000, /* CB_COLOR7_CMASK */
    0x00000000, /* CB_COLOR7_CMASK_SLICE */
    0x00000000, /* CB_COLOR7_FMASK */
    0x00000000, /* CB_COLOR7_FMASK_SLICE */
    0x00000000, /* CB_COLOR7_CLR_WORD0 */
    0x00000000, /* CB_COLOR7_CLR_WORD1 */
};

static struct clearstate_extent_def section_ctx_defs[] = {
    {section_ctx_def_0, 0x00000000, 212 },
    {section_ctx_def_1, 0x000000d8, 272 },
    {section_ctx_def_2, 0x000001f5, 6 },
    {section_ctx_def_3, 0x00000200, 157 },
    {section_ctx_def_4, 0x000002a1, 1 },
    {section_ctx_def_5, 0x000002a3, 1 },
    {section_ctx_def_6, 0x000002a5, 233 },
    { 0, 0, 0 }
};

struct clearstate_section_def clearstate_data[] = {
    { section_ctx_defs, SECTION_ID_CTX },
    { 0, SECTION_ID_NONE }
};

/* see clearstate_to_gpu */
u32 clearstate_dws_n(void)
{
	u32 cnt;
	struct clearstate_section_def *sect;
	struct clearstate_extent_def *ext;

	cnt = 0;

	/* begin clear state */
	cnt += 2;
	/* ctx ctl state */
	cnt += 3;

	for (sect = &clearstate_data[0]; sect->section != NULL; ++sect) {
		for (ext = sect->section; ext->extent != NULL; ++ext) {
			if (sect->id == SECTION_ID_CTX)
				cnt += 2 + ext->reg_cnt;
			else
				return 0;
		}
	}

	/* pa_sc_raster_cfg */
	cnt += 3;
	/* end clr state */
	cnt += 2;
	/* clear state */
	cnt += 2;
	return cnt;
}

/* we start to copy the reg values *after* the header of 256 bytes */
#define WR_GPU(x) vram_w32(dev, (x), \
				dd->rlc.clr_restore + 256 + ((cnt++) << 2));
static void clearstate_to_rlc(struct pci_dev *dev)

{
	struct dev_drv_data *dd;
	u32 cnt;
	const struct clearstate_section_def *sect;
	const struct clearstate_extent_def *ext;
	u32 reg;

	dd = pci_get_drvdata(dev);

	cnt = 0;
	/* begin clear state */
	WR_GPU(PKT3(PKT3_PREAMBLE_CTL, 1));
	WR_GPU(PKT3_PREAMBLE_BEGIN_CLR_STATE);

	/* ctx ctl state */
	WR_GPU(PKT3(PKT3_CTX_CTL, 2));
	WR_GPU(0x80000000);
	WR_GPU(0x80000000);

	for (sect = clearstate_data; sect->section != NULL; ++sect) {
		for (ext = sect->section; ext->extent != NULL; ++ext) {
			if (sect->id == SECTION_ID_CTX) {
				WR_GPU(PKT3(PKT3_SET_CTX_REG, ext->reg_cnt + 1));
				WR_GPU(ext->reg_idx);
				for (reg = 0; reg < ext->reg_cnt; ++reg)
					WR_GPU(ext->extent[reg]);
			} else {
				return;
			}
		}
	}

	/* pa_sc_raster_cfg */
	WR_GPU(PKT3(PKT3_SET_CTX_REG, 2));
	WR_GPU(CTX_REG_IDX(PA_SC_RASTER_CFG));
	switch (dd->family) {
	case TAHITI:
	case PITCAIRN:
		WR_GPU(0x2a00126a);
		break;
	case VERDE:
		WR_GPU(0x0000124a);
		break;
	case OLAND:
		WR_GPU(0x00000082);
		break;
	default:
		WR_GPU(0x00000000);
	}

	/* end clr state */
	WR_GPU(PKT3(PKT3_PREAMBLE_CTL, 1));
	WR_GPU(PKT3_PREAMBLE_END_CLR_STATE);
	
	/* clear state */
	WR_GPU(PKT3(PKT3_CLR_STATE, 1));
	WR_GPU(0);
}

long clearstate_init(struct pci_dev *dev)
{
	struct dev_drv_data *dd;
	u32 dws_n;
	u32 full_dws_n;
	long r;
	u64 mc_regs_gpu_addr;

	dws_n = clearstate_dws_n();
	full_dws_n = (256 >> 2) + dws_n; /* leave some room at the begining */

	dd = pci_get_drvdata(dev);

	r = rng_alloc_align(&dd->rlc.clr_restore, &dd->vram.mng,
						full_dws_n << 2, GPU_PAGE_SZ);
	if (r != 0) {
		dev_err(&dev->dev,
			"unable to alloc GPU RLC clear and restore page\n");
		return -SI_ERR;
	}

	mc_regs_gpu_addr = 256 + dd->rlc.clr_restore;
	/* XXX:  the rlc is expecting upper bits in first dword */
	vram_w32(dev, upper_32_bits(mc_regs_gpu_addr), dd->rlc.clr_restore);
	vram_w32(dev, lower_32_bits(mc_regs_gpu_addr),
						dd->rlc.clr_restore + 4);
	vram_w32(dev, dws_n, dd->rlc.clr_restore + 8);
	clearstate_to_rlc(dev);
	return 0;
}
